package projectmanagement

import (
	"errors"
	"github.com/sirupsen/logrus"
	"gorm.io/driver/sqlite"
	"gorm.io/gorm"
	"gorm.io/gorm/logger"
	"playbook/ginsvr/src/global"
	"playbook/ginsvr/src/orm"
	"playbook/ginsvr/src/utils/fileutil"
	"playbook/ginsvr/src/utils/uuidutil"
)

var db *gorm.DB
var err error

func init() {
	db, err = gorm.Open(sqlite.Open("playbook.db"), &gorm.Config{Logger: logger.Default.LogMode(logger.Info)})
}

type FullProject struct {
	Project Project `json:"project"`
}

type Project struct {
	Projectid   string `json:"id"`
	Projectname string `json:"projectname"`
	Projectdesc string `json:"projectdesc"`
	Createuser  string `json:"createuser"`
	Projectpath string `json:"projectpath"`
}

// 项目创建相关方法
func AddProject(fullProject FullProject) (orm.Response, error) {
	var resp orm.Response
	project := fullProject.Project
	if project.Projectpath == "" {
		resp.RespCode = "000002"
		resp.RespMsg = "projectpath can not be null!"
		return resp, errors.New("projectpath can not be null!")
	}
	if project.Projectname == "" {
		resp.RespCode = "000003"
		resp.RespMsg = "projectname can not be null!"
		return resp, errors.New("projectname can not be null!")
	}
	// 项目唯一性校验
	var count int64
	db.Table("project").Where("projectname = ?", project.Projectname).Count(&count)
	if count > 0 {
		resp.RespCode = "000001"
		resp.RespMsg = "project already exist"
		return resp, errors.New("project already exist")
	}
	// 创建本地文件夹
	srcPath := orm.GetGeneSrcDefine("composebean").Srcpath
	srcJsonPath := orm.GetGeneSrcDefine("composejson").Srcpath
	pathList := []string{srcPath, srcJsonPath}
	errDir := fileutil.MakeDir(project.Projectpath, pathList)
	if errDir != nil {
		resp.RespCode = "000004"
		resp.RespMsg = errDir.Error()
		return resp, nil
	}
	projectid := uuidutil.GetUUID()
	err := db.Table("project").CreateInBatches([]map[string]interface{}{{
		"projectid":   projectid,
		"projectname": project.Projectname,
		"createuser":  project.Createuser,
		"projectdesc": project.Projectdesc,
		"projectpath": project.Projectpath,
	}}, 1)
	if err.Error != nil {
		global.LOG.WithFields(logrus.Fields{
			"err":       err,
			"projectid": projectid,
		}).Error("create project err.")
		resp.RespCode = "000005"
		resp.RespMsg = err.Error.Error()
		return resp, nil
	}
	resp.RespCode = "000000"
	resp.RespMsg = projectid
	return resp, nil
}

// 项目更新相关方法
func UpdateProject(fullProject FullProject) (orm.Response, error) {
	var resp orm.Response
	project := fullProject.Project
	var originproject Project
	db.Table("project").Where("projectid = ?", project.Projectid).Find(&originproject)
	// 项目唯一性校验
	if project.Projectname != originproject.Projectname {
		var count int64
		db.Table("project").Where("projectname = ?", project.Projectname).Count(&count)
		if count > 0 {
			resp.RespCode = "000001"
			resp.RespMsg = "project already exist"
			return resp, errors.New("project already exist")
		}
	}

	// 复制项目文件到新的项目目录下
	srcPath := orm.GetGeneSrcDefine("composebean").Srcpath
	srcJsonPath := orm.GetGeneSrcDefine("composejson").Srcpath
	localpath := orm.GetLocalPath(global.USER)
	sourcePath := localpath.LocalPath + global.PTHSEP + originproject.Projectpath + global.PTHSEP + srcPath
	targetPath := localpath.LocalPath + global.PTHSEP + project.Projectpath + global.PTHSEP + srcPath
	// 如果项目路径未发生改变，不做文件的处理
	if originproject.Projectpath != project.Projectpath {
		errs := fileutil.CopyDir(sourcePath, targetPath)
		if errs != nil {
			resp.RespCode = "000002"
			resp.RespMsg = errs.Error()
			return resp, errs
		}
		sourceJsonPath := localpath.LocalPath + global.PTHSEP + originproject.Projectpath + global.PTHSEP + srcJsonPath
		targetJsonPath := localpath.LocalPath + global.PTHSEP + project.Projectpath + global.PTHSEP + srcJsonPath
		errJson := fileutil.CopyDir(sourceJsonPath, targetJsonPath)
		if errJson != nil {
			resp.RespCode = "000002"
			resp.RespMsg = errJson.Error()
			return resp, errJson
		}

		// 删除旧项目路径下的文件
		sourcePathList := []string{sourcePath, sourceJsonPath}
		err := fileutil.DeleteProjectFile(sourcePathList)
		if err != nil {
			resp.RespCode = "000003"
			resp.RespMsg = "remove project file err"
			return resp, err
		}
	}
	// 更新有变化的属性
	err := db.Table("project").Where("projectid=?  ", project.Projectid).Updates(project)
	if err.Error != nil {
		global.LOG.WithFields(logrus.Fields{
			"err":       err,
			"projectid": project.Projectid,
		}).Error("update project err.")
		resp.RespCode = "000004"
		resp.RespMsg = err.Error.Error()
		return resp, errors.New(err.Error.Error())
	}
	resp.RespCode = "000000"
	resp.RespMsg = "project update success!"

	return resp, nil
}

// 通过项目id查询项目路径
func GetProjectPathById(projectid string) interface{} {
	var dataMap = make(map[string]interface{})
	var count int64
	db.Table("project").Where("projectid = ?", projectid).Count(&count)
	if count == 0 {
		dataMap["respCode"] = "000001"
		dataMap["respMsg"] = "project not found"
		return dataMap
	}
	var projectList []Project
	db.Table("project").Where("projectid = ?", projectid).Find(&projectList)
	dataMap["respCode"] = "000000"
	dataMap["projectpath"] = projectList[0].Projectpath
	return dataMap
}

// 项目列表查询
func GetProjectList(projectname string, page int, pagesize int) interface{} {
	var total int64
	db.Table("project").Where("projectname like ?", projectname+"%").Count(&total)
	var projectList []Project
	db.Table("project").Where("projectname like ?", projectname+"%").Limit(pagesize).Offset((page - 1) * pagesize).Find(&projectList)
	var dataMap = make(map[string]interface{})
	dataMap["total"] = total
	dataMap["data"] = projectList
	return dataMap
}

// 查询服务端项目列表信息
func GetServerProjectList() (orm.Response, error) {
	var resp orm.Response
	var projectList []Project
	var projectid string
	srcPath := orm.GetGeneSrcDefine("composebean").Srcpath
	srcJsonPath := orm.GetGeneSrcDefine("composejson").Srcpath
	srcPathList := []string{srcPath, srcJsonPath}
	db.Table("project").Find(&projectList)
	for _, project := range projectList {
		projectid = project.Projectid
		var total int64
		db.Table("project").Where("projectid = ?", projectid).Count(&total)
		if total > 0 {
			err := db.Table("project").Where("projectid=? ", project.Projectid).Updates(project).Error
			if err != nil {
				resp.RespCode = "000001"
				resp.RespMsg = "Synchronization failed"
				return resp, errors.New("Synchronization failed")
			}
		} else if total == 0 {
			err := db.Table("project").CreateInBatches([]map[string]interface{}{{
				"projectid":   project.Projectid,
				"projectname": project.Projectname,
				"createuser":  project.Createuser,
				"projectdesc": project.Projectdesc,
				"projectpath": project.Projectpath,
			}}, 1)
			if err != nil {
				resp.RespCode = "000001"
				resp.RespMsg = "Synchronization failed"
				return resp, errors.New("Synchronization failed")
			}
		}
		err := fileutil.MakeDir(project.Projectpath, srcPathList)
		if err != nil {
			resp.RespCode = "000002"
			resp.RespMsg = "dir creat err"
			return resp, err
		}
	}
	resp.RespCode = "000000"
	resp.RespMsg = "Synchronization Succeeded"
	return resp, nil
}
